using System.Globalization;
using System.Net.Http.Json;
using System.Text.Json.Serialization;
using WeatherMcpServer.Data.Entities;

namespace WeatherMcpServer.Services.Weather;

/// <summary>
/// 基于 Open-Meteo 的天气提供器实现（无需密钥）。
/// 仅作为第二数据源以支持主备/融合，不改变默认单源行为。
/// </summary>
public sealed class OpenMeteoWeatherProvider : IWeatherProvider
{
    private readonly HttpClient _http;

    /// <summary>
    /// 构造函数，注入 <see cref="IHttpClientFactory"/>。
    /// </summary>
    public OpenMeteoWeatherProvider(IHttpClientFactory httpClientFactory)
    {
        _http = httpClientFactory.CreateClient();
    }

    /// <inheritdoc />
    public async Task<ProviderForecast?> GetForecastAsync(double latitude, double longitude, int dayOffset = 0, CancellationToken ct = default)
    {
        if (dayOffset < 0) dayOffset = 0; if (dayOffset > 2) dayOffset = 2;
        // 请求每日聚合：最高/最低温、降水量、最大风速
        var latStr = latitude.ToString(CultureInfo.InvariantCulture);
        var lonStr = longitude.ToString(CultureInfo.InvariantCulture);
        var url = $"https://api.open-meteo.com/v1/forecast?latitude={latStr}&longitude={lonStr}&daily=temperature_2m_max,temperature_2m_min,precipitation_sum,windspeed_10m_max&timezone=auto";
        var resp = await _http.GetAsync(url, ct);
        if (!resp.IsSuccessStatusCode) return null;
        var data = await resp.Content.ReadFromJsonAsync<OpenMeteoDailyResponse>(cancellationToken: ct);
        if (data?.Daily is null) return null;
        if (data.Daily.TemperatureMax is null || data.Daily.TemperatureMin is null || data.Daily.PrecipitationSum is null || data.Daily.WindspeedMax is null)
            return null;
        if (data.Daily.TemperatureMax.Length <= dayOffset) return null;

        double? tmax = data.Daily.TemperatureMax[dayOffset];
        double? tmin = data.Daily.TemperatureMin[dayOffset];
        double? rain = data.Daily.PrecipitationSum[dayOffset];
        double? wind = data.Daily.WindspeedMax[dayOffset];

        var types = new List<WeatherType>();
        if (rain.HasValue && rain.Value >= 25) types.Add(WeatherType.HeavyRain);
        if (wind.HasValue && wind.Value >= 6) types.Add(WeatherType.Wind);

        return new ProviderForecast(
            RegionCode: null, // Open-Meteo 不返回 adcode
            RegionName: null,
            TemperatureMax: tmax,
            TemperatureMin: tmin,
            RainMm: rain,
            WindLevel: wind,
            Types: types
        );
    }

    // 简化的 Open-Meteo 日级响应模型
    private sealed class OpenMeteoDailyResponse
    {
        [JsonPropertyName("daily")] public DailyBlock? Daily { get; set; }
        public sealed class DailyBlock
        {
            [JsonPropertyName("time")] public string[]? Time { get; set; }
            [JsonPropertyName("temperature_2m_max")] public double[]? TemperatureMax { get; set; }
            [JsonPropertyName("temperature_2m_min")] public double[]? TemperatureMin { get; set; }
            [JsonPropertyName("precipitation_sum")] public double[]? PrecipitationSum { get; set; }
            [JsonPropertyName("windspeed_10m_max")] public double[]? WindspeedMax { get; set; }
        }
    }
}
